/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cbrtator.graph;

import com.mxgraph.model.mxCell;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.view.mxGraph;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;



import javax.swing.filechooser.FileFilter;

import javax.swing.filechooser.FileSystemView;
import opennlp.grokkit.gui.ExtensionFileFilter;

/**
 *
 * @author Gianfranco
 */
public class visualisation extends JPanel{
    private mxGraph graph = new mxGraph();
    public int c=0;
    private mxGraphComponent component;
    private JTextField text;
    private JButton buttonADD;
    private JButton buttonDEL;
    private JButton buttonSAVE;
    private JButton buttonLOAD;
    private JLabel lab;
    private int largeur= 100;
    private int hauteur= 50;
    
    private int largeurPanel;
    private int hauteurPanel;
    
    Object cell;
    ArrayList<mxCell> celle = new ArrayList<mxCell>(); 
    ArrayList<Object> ligne = new ArrayList<Object>(); 
    
    /**
     * constructeur
     */
    public visualisation(int l, int h)
    {
        super();
        this.largeurPanel = l;
        this.hauteurPanel = h;
        init();
        initNEW();
    }

    /**
     * Initialise l'interface
     */
    private void init()
    {
        
        setSize(largeurPanel,hauteurPanel);
        graph = new mxGraph();
        component = new mxGraphComponent(graph);
        component.setPreferredSize(new Dimension(this.largeurPanel,this.hauteurPanel));
        
        this.add(component, -1);
        
        lab = new JLabel("Nom symbole: ");
        
        this.add(lab);
        
        text = new JTextField();
        this.add(text);
        text.setPreferredSize(new Dimension(150,21));
        setLayout(new FlowLayout(FlowLayout.LEFT));
        
        buttonADD = new JButton("Ajouter");
        buttonADD.setName("ajouter");
        this.add(buttonADD);
        buttonADD.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) 
            {
                graph.getModel().beginUpdate();
                Object parent = graph.getDefaultParent();
                celle.add((mxCell)graph.insertVertex(parent, null, text.getText(), 0, 0, 100, 50)  );
           
                graph.getModel().endUpdate();
            }
        });
        

        buttonDEL = new JButton("Supprimer");
        buttonDEL.setName("supprimer");
        this.add(buttonDEL);
        buttonDEL.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) 
            {
                graph.getModel().remove(cell);
                
                for(int i = 0; i<celle.size(); i++)
                {
                    if(cell == celle.get(i))
                        celle.remove(i);
                }
                
                
            }
        });
        
        buttonSAVE = new JButton("Sauvegarder");
        buttonSAVE.setName("sauvegarder");
        this.add(buttonSAVE);
        buttonSAVE.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg1) 
            {
                try {
                    save();
                } catch (IOException ex) {
                    Logger.getLogger(visualisation.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        buttonLOAD = new JButton("Ouvrir");
        buttonLOAD.setName("load");
        this.add(buttonLOAD);
        buttonLOAD.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg1) 
            {
                try {
                    openGraphe("mongraphe");
                } catch (IOException ex) {
                    Logger.getLogger(visualisation.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
         component.getGraphControl().addMouseListener(new MouseListener() {

            public void mouseClicked(MouseEvent e) {
                
                cell = component.getCellAt(e.getX(), e.getY());
                
            }

            public void mousePressed(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            public void mouseReleased(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            public void mouseEntered(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            public void mouseExited(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }
        });
    }
          
    /**
     * ajoute l'element root (pour le nouveau graphe)
     */
    private void initNEW() 
    {           
        
        graph.getModel().beginUpdate();
        Object parent = graph.getDefaultParent();
        celle.add((mxCell)graph.insertVertex(parent, null, "ROOT", 150, 5, 100, 50)  );
        graph.getModel().endUpdate();
               
    }
    
    /**
     * Ouvre un graphe
     * @param file_name Nom du ficher
     * @throws FileNotFoundException
     * @throws IOException 
     */
    public void openGraphe(String file_name) throws FileNotFoundException, IOException
    {
        
        
        String x = openFileGraphe();
        if(x == null)
            return;
        System.out.println("LOAD GRAPHE");
        File dir = new File("./save_graphe");
        if(!dir.exists())
        {
            return;
        }
        

        File f = new File(x);
        if(x == null)
            return;
        if(!f.exists())
        {
            return;
        }

        if(f!=null)
        {    
            
            FileInputStream fstream = new FileInputStream(f);
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String strLine;

            for(int i =0; i<celle.size(); i++)
            {
                graph.getModel().remove((mxCell)celle.get(i));
            }

            celle = new ArrayList<mxCell>(); 

            for(int i =0; i<ligne.size(); i++)
            {

                graph.getModel().remove(ligne.get(i));            
            }
            ligne = new ArrayList<Object>();

            while ((strLine = br.readLine()) != null)   
            {       
                String[] split = strLine.split(" ");
                if(split[0].equals("CELLE"))
                {
                    System.out.println("CREATE CELLE "+split[1]+" int: "+Double.valueOf(split[2]));
                    graph.getModel().beginUpdate();
                    Object parent = graph.getDefaultParent();
                    celle.add((mxCell)graph.insertVertex(parent, null, split[1], Double.valueOf(split[2]), Double.valueOf(split[3]), Integer.valueOf(split[4]), Integer.valueOf(split[5]))  );
                    graph.getModel().endUpdate();
                }
                if(split[0].equals("LIGNE"))
                {
                    System.out.println("CREATE LIGNE");
                    graph.getModel().beginUpdate();
                    Object parent = graph.getDefaultParent();

                    double originDouble1 =  Double.valueOf(split[1]);
                    double destinationDouble1 =  Double.valueOf(split[2]);                
                    Object origin = component.getCellAt((int)originDouble1, (int)destinationDouble1);

                    double originDouble2 =  Double.valueOf(split[3]);
                    double destinationDouble2 =  Double.valueOf(split[4]);
                    Object destination = component.getCellAt((int)originDouble2, (int)destinationDouble2);

                    ligne.add(graph.insertEdge(parent, null, "", origin, destination));

                    graph.getModel().endUpdate();
                }
            }       
    }
    }
    /**
     * Sauvegarde le graphe dans un ficher
     * @param file_name Nom du ficher
     * @throws IOException 
     */
    public void save() throws IOException
    {
        FileSystemView vueSysteme = FileSystemView.getFileSystemView();
        //récupération des répertoires
        File home = vueSysteme.getHomeDirectory(); 
        //mise en place d'un filtre sur les fichiers
        FileFilter tatorfilter = new ExtensionFileFilter("gtr");

        JFileChooser homeChooser = new JFileChooser(home);
        homeChooser.addChoosableFileFilter(tatorfilter);


        int returnVal = homeChooser.showSaveDialog(null);
        
         if (returnVal == JFileChooser.APPROVE_OPTION) 
         {
                
                File f = new File(homeChooser.getSelectedFile().getAbsoluteFile()+".gtr");

                if(f == null)
                {
                    return;
                }
                else
                {                                                               
                    ArrayList<String> lignes = new ArrayList<String>();
                    FileWriter fstream = new FileWriter(f);
                    BufferedWriter print = new BufferedWriter(fstream);        

                    for (int i = 0; i<celle.size(); i++)
                    {
                        print.write("CELLE "+celle.get(i).getValue().toString()+" "+celle.get(i).getGeometry().getX()+" "+celle.get(i).getGeometry().getY()+" "+largeur+" "+hauteur+"\n");                       
                        if(celle.get(i).getEdgeCount()>0)
                        {
                            for( int j = 0; j<celle.get(i).getEdgeCount(); j++)
                            {
                                    mxCell cc = (mxCell) celle.get(i).getEdgeAt(0);
                                    String l = ""+cc.getSource().getGeometry().getX()+" "+cc.getSource().getGeometry().getY()+" "+cc.getTarget().getGeometry().getX()+" "+cc.getTarget().getGeometry().getY();

                                        lignes.add(l);

                            }
                        }
                    }        
                    for(int i = 0; i<lignes.size(); i++)
                    {            
                        print.write("LIGNE "+lignes.get(i)+"\n");        
                    }

                    print.close();
                    JOptionPane.showMessageDialog(this, "Ficher sauvegardé");
                }
                
         }
    }
   
    
    public String openFileGraphe()
    {     
        FileSystemView vueSysteme = FileSystemView.getFileSystemView();
        

        File home = vueSysteme.getHomeDirectory(); 

        FileFilter tatorfilter = new ExtensionFileFilter("gtr");

        JFileChooser homeChooser = new JFileChooser(home);
        homeChooser.addChoosableFileFilter(tatorfilter);

        
        homeChooser.showOpenDialog(null);
        if(homeChooser.getSelectedFile() == null)
            return null;
        System.out.println("Path: "+homeChooser.getSelectedFile().getAbsolutePath());
        return homeChooser.getSelectedFile().getAbsolutePath();
    }
}
